package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/service"
	"go.uber.org/zap"
)

// SimpleEmbeddingModel 简单的嵌入模型实现，用于测试
// 它返回固定向量而不是实际调用嵌入服务
type SimpleEmbeddingModel struct{}

// Embedding 返回固定向量
func (m *SimpleEmbeddingModel) Embedding(ctx context.Context, text string) ([]float32, error) {
	// 返回一个固定大小的向量，实际应用中应该调用嵌入服务
	return make([]float32, 768), nil
}

// BatchEmbedding 批量返回固定向量
func (m *SimpleEmbeddingModel) BatchEmbedding(ctx context.Context, texts []string) ([][]float32, error) {
	// 返回固定大小的向量数组
	vectors := make([][]float32, len(texts))
	for i := range texts {
		vectors[i] = make([]float32, 768)
	}
	return vectors, nil
}

// Close 关闭模型资源
func (m *SimpleEmbeddingModel) Close() error {
	return nil
}

// GetModelInfo 返回模型信息
func (m *SimpleEmbeddingModel) GetModelInfo() map[string]interface{} {
	return map[string]interface{}{
		"name":        "SimpleEmbeddingModel",
		"description": "Simple embedding model for testing",
		"dimension":    768,
	}
}

func main() {
	// 初始化日志
	zapLogger, err := zap.NewProduction()
	if err != nil {
		log.Fatalf("Failed to initialize logger: %v", err)
	}
	defer zapLogger.Sync()

	// 初始化全局logger
	logger.InitLogger()

	// 加载配置
	cfg, err := config.LoadConfig()
	if err != nil {
		zapLogger.Fatal("Failed to load config", zap.Error(err))
	}

	// 启用语义分块
	cfg.FileIndex.SemanticChunking = true
	cfg.FileIndex.MinChunkSize = 200
	cfg.FileIndex.MaxChunkSize = 1000

	// 创建简单的嵌入模型
	embeddingModel := &SimpleEmbeddingModel{}

	// 创建文件处理器
	fileProcessor := service.NewFileProcessor(embeddingModel, &cfg.FileIndex)

	// 读取测试文件
	testFilePath := "./test/测试分块文本.md"
	content, err := ioutil.ReadFile(testFilePath)
	if err != nil {
		zapLogger.Fatal("Failed to read test file", zap.Error(err))
	}

	// 转换为UTF-8编码
	text := string(content)

	// 记录开始时间
	startTime := time.Now()

	// 使用语义分块处理文本
	fmt.Println("开始语义分块测试...")
	chunks, err := fileProcessor.ProcessFile(testFilePath)
	if err != nil {
		zapLogger.Fatal("Failed to process file", zap.Error(err))
	}

	// 计算处理时间
	duration := time.Since(startTime)

	// 输出分块结果
	fmt.Printf("\n分块完成！共生成 %d 个分块，耗时 %v\n\n", len(chunks), duration)

	// 输出每个分块的信息
	for i, chunk := range chunks {
		fmt.Printf("=== 分块 %d (长度: %d) ===\n", i+1, len(chunk.Content))
		fmt.Printf("起始位置: %d, 结束位置: %d\n", chunk.StartPos, chunk.EndPos)
		fmt.Printf("内容预览: %s...\n\n", chunk.Content[:min(200, len(chunk.Content))])
	}

	// 统计信息
	totalLength := 0
	minSize := len(chunks[0].Content)
	maxSize := len(chunks[0].Content)
	for _, chunk := range chunks {
		size := len(chunk.Content)
		totalLength += size
		if size < minSize {
			minSize = size
		}
		if size > maxSize {
			maxSize = size
		}
	}

	avgSize := totalLength / len(chunks)
	fmt.Printf("\n=== 分块统计信息 ===\n")
	fmt.Printf("原始文本长度: %d\n", len(text))
	fmt.Printf("分块总数: %d\n", len(chunks))
	fmt.Printf("最小分块大小: %d\n", minSize)
	fmt.Printf("最大分块大小: %d\n", maxSize)
	fmt.Printf("平均分块大小: %d\n", avgSize)
	fmt.Printf("处理时间: %v\n", duration)
}

// min 返回两个整数中的较小值
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}